package com.gyg.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.gyg.constant.CloudConstant;
import com.gyg.domain.*;
import com.gyg.dao.CloudVideoMapper;
import com.gyg.enums.FileOperateEnum;
import com.gyg.enums.FileTypeEnum;
import com.gyg.returns.RespCode;
import com.gyg.returns.RespEntity;
import com.gyg.service.*;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gyg.utils.FileUtil;
import com.gyg.utils.TimeUtilCustomize;
import com.gyg.vo.param.*;
import com.gyg.vo.result.CloudInfoResult;
import com.gyg.vo.result.FileDownloadResult;
import com.gyg.vo.result.VideoListResult;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.Date;
import java.util.Objects;

/**
 * <p>
 * 视频信息表 服务实现类
 * </p>
 *
 * @author gyg
 * @since 2021-04-14
 */
@Service
public class CloudVideoServiceImpl extends ServiceImpl<CloudVideoMapper, CloudVideo> implements CloudVideoService {

    @Autowired
    private CloudRecordService cloudRecordService;

    @Autowired
    private CloudSpaceService cloudSpaceService;

    @Autowired
    private CloudTrashService cloudTrashService;

    @Autowired
    private CloudCollectionService cloudCollectionService;

    @Override
    public RespEntity uploadVideo(FileParam fileParam) {

        //本次上传文档总大小
        BigDecimal sizeTotal = new BigDecimal(fileParam.getSize());
        //校验云盘空间是否充足
        Integer userId = fileParam.getUserId();
        Integer check = cloudSpaceService.checkCloudSpace(sizeTotal.longValue(), userId);
        if (check.equals(1)) {
            //空间不足
            return new RespEntity(RespCode.SIZE_NOT_ENOUGH);
        }

        //空间充足 开始上传
        //当前时间
        String time = TimeUtilCustomize.parseDateToStr(TimeUtilCustomize.DATE_TIME_FORMAT, new Date());
        //当前时间 格式 yyyy-MM-dd
        String dtD = TimeUtilCustomize.parseDateToStr(TimeUtilCustomize.DATE_DAY_FORMAT, new Date());

        //数据组装
        CloudVideo cloudVideo = CloudVideo.builder()
                .userId(fileParam.getUserId())
                .videoName(fileParam.getFilename())
                .videoUrl(fileParam.getUrl())
                .videoSize(FileUtil.getSize(fileParam.getSize()))
                .videoByte(fileParam.getSize() + "")
                .videoType(fileParam.getType())
                .videoImg(CloudConstant.SYSTEM_VIDEO)
                .videoTime(time)
                .build();
        baseMapper.insert(cloudVideo);

        //操作记录 异步接入
        CloudRecord cloudRecord = CloudRecord.builder()
                .userId(fileParam.getUserId())
                .fileId(cloudVideo.getId())
                .fileType(FileTypeEnum.VIDEO.getCode())
                .fileOperate(FileOperateEnum.UPLOAD.getCode())
                .recordTime(time)
                .dtD(dtD)
                .build();
        cloudRecordService.fileRecordAccess(cloudRecord);

        return new RespEntity(RespCode.SUCCESS);
    }

    @Override
    public Long getVideoByte(Integer userId) {
        return baseMapper.getVideoByte(userId);
    }

    @Override
    public RespEntity<VideoListResult> cloudVideoList(Integer userId, Integer pageSize, Integer pageNum, String content) {
        //条件查询
        QueryWrapper<CloudVideo> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(CloudVideo::getUserId, userId)
                .eq(CloudVideo::getDeleted, 0);
        if (StringUtils.isNoneBlank(content)) {
            queryWrapper.lambda().like(CloudVideo::getVideoName, content);
        }
        queryWrapper.lambda().orderByDesc(CloudVideo::getId);

        //逻辑分页
        IPage<CloudVideo> iPage = new Page<>(pageSize, pageNum);
        IPage<CloudVideo> page = super.page(iPage, queryWrapper);

        //数据组装
        VideoListResult videoListResult = new VideoListResult();
        videoListResult.setPageNum(page.getCurrent());
        videoListResult.setPageSize(page.getSize());
        videoListResult.setPageCount(page.getPages());
        videoListResult.setTotal(page.getTotal());
        videoListResult.setCloudVideoList(page.getRecords());

        return new RespEntity<>(RespCode.SUCCESS, videoListResult);
    }

    @Override
    public RespEntity editVideo(UpdateFileParam updateFileParam) {
        CloudVideo cloudVideo = CloudVideo.builder()
                .id(updateFileParam.getFileId())
                .videoName(updateFileParam.getFileName())
                .build();
        baseMapper.updateById(cloudVideo);

        return new RespEntity(RespCode.SUCCESS);
    }

    @Override
    public RespEntity deleteVideo(Integer videoId) {
        CloudVideo cloudVideo = CloudVideo.builder()
                .id(videoId)
                .deleted(1)
                .build();
        baseMapper.updateById(cloudVideo);

        CloudVideo video = baseMapper.selectById(videoId);

        //添加回收站信息
        cloudTrashService.addCloudTrash(new TrashParam(video.getUserId(),
                video.getId(), FileTypeEnum.VIDEO.getCode()));

        //查询占用容量
        QueryWrapper<CloudSpace> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(CloudSpace::getUserId, video.getUserId())
                .eq(CloudSpace::getDeleted, 0);
        CloudSpace cloudSpace = cloudSpaceService.getOne(queryWrapper);

        //计算最新占用容量
        BigDecimal newPictureByte = new BigDecimal(cloudSpace.getSpaceUsedByte()).subtract(new BigDecimal(video.getVideoByte()));

        //更新云盘容量
        cloudSpace.setSpaceUsedByte(newPictureByte + "");
        cloudSpace.setSpaceUsedSize(FileUtil.getSize(newPictureByte.longValue()));
        cloudSpaceService.updateById(cloudSpace);

        //取消收藏
        CollectionParam collectionParam = new CollectionParam();
        collectionParam.setUserId(video.getUserId());
        collectionParam.setFileId(video.getId());
        collectionParam.setFileType(FileTypeEnum.VIDEO.getCode());
        cloudCollectionService.cancelCollection(collectionParam);

        return new RespEntity(RespCode.SUCCESS);
    }

    @Override
    public RespEntity videoCloudInfo(Integer userId) {
        QueryWrapper<CloudVideo> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(CloudVideo::getUserId, userId)
                .eq(CloudVideo::getDeleted, 0);
        //视频总数量
        Integer count = baseMapper.selectCount(queryWrapper);
        queryWrapper.select("MAX(video_time) AS video_time");
        CloudVideo cloudVideo = baseMapper.selectOne(queryWrapper);

        String date = "暂无最近上传时间";
        if (Objects.nonNull(cloudVideo)) {
            date = cloudVideo.getVideoTime();
        }

        CloudInfoResult cloudInfoResult = CloudInfoResult.builder()
                .count(count)
                .date(date)
                .build();

        return new RespEntity<>(RespCode.SUCCESS, cloudInfoResult);
    }

    @Override
    public RespEntity<FileDownloadResult> download(DownloadParam downloadParam) {
        //获取阿里云OSS上的文件路径 objectName
        CloudVideo cloudVideo = baseMapper.selectById(downloadParam.getFileId());
        String videoUrl = cloudVideo.getVideoUrl();
        String objectName = videoUrl.split("http://gaoyiguan.cn/")[1];

        //数据组装
        FileDownloadResult fileDownloadResult = new FileDownloadResult();
        fileDownloadResult.setObjectName(objectName);
        fileDownloadResult.setFilename(cloudVideo.getVideoName());

        //更新下载次数
        cloudVideo.setVideoDownload(cloudVideo.getVideoDownload() + 1);
        baseMapper.updateById(cloudVideo);

        //当前时间 格式 yyyy-MM-dd HH:mm:ss
        String time = TimeUtilCustomize.parseDateToStr(TimeUtilCustomize.DATE_TIME_FORMAT, new Date());
        //当前时间 格式 yyyy-MM-dd
        String dtD = TimeUtilCustomize.parseDateToStr(TimeUtilCustomize.DATE_DAY_FORMAT, new Date());

        //操作记录 异步接入
        CloudRecord cloudRecord = CloudRecord.builder()
                .userId(cloudVideo.getUserId())
                .fileId(cloudVideo.getId())
                .fileType(FileTypeEnum.VIDEO.getCode())
                .fileOperate(FileOperateEnum.DOWNLOAD.getCode())
                .recordTime(time)
                .dtD(dtD)
                .build();
        cloudRecordService.fileRecordAccess(cloudRecord);

        return new RespEntity<>(RespCode.SUCCESS, fileDownloadResult);
    }

}
